home *** CD-ROM | disk | FTP | other *** search
- {**************************************************************************
- Some of the DOS memory routines presented in ALLOC.PAS and demonstrated
- in ALLOCDEM.PAS, were initially uploaded by Richard Sadowsky as DOSMEM
- (version 1.1), and released to the public domain on 8/22/88. That
- unit was especially appreciated by those of us who code in both
- Turbo Pascal and Turbo C. 30-40% of the code in the ALLOC unit was
- taken from DOSMEM.
-
- However, DOSMEM had its DOS routines written in assembly language,
- and required use as external *.obj files. Since I frequently forget
- *.obj files when I'm working at differenct locations, and more importantly,
- since I'm not good at assembly, I re-wrote the routines using interrupts,
- calling the new unit ALLOC.PAS, in deference to Turbo C's <alloc.h>. In
- addition, a few other modifications were made to the error-handling routine,
- as well as making the interrupt routines internal to the unit, re-naming
- a few things, and adding calloc, which has as its argument, the desired
- fillpattern with which to clear the RAM block (unlike C's calloc).
- See ALLOC.PAS for modification history.
-
- Robert L. Jones, CIS [71251,2566]
- Version 1.4 released to the public domain 4/9/89.
- ***************************************************************************}
-
-
- {$M 1024,0,0}
- { \ memory should be returned to DOS to enable ALLOC functions to
- work, since Turbo Pascal will assign any extra RAM to the
- heap, which isn't accessible to the ALLOC routines. This does
- not mean that a portion cannot be retained for the heap, but
- rather that enough RAM must be available for DOS if you want
- to allocate some of it using ALLOC. See ALLOC.PAS for details.
-
- if you want to see why it's required, temporarily erase
- "$M" and run the demo.
- }
-
- {$R-,S-}
-
-
- program allocdemo;
-
- uses crt, ALLOC;
-
- const
- ScreenSize = 4000;
- MaxNum = 4;
-
- var
- p, videoptr : pointer;
- pbuffer : array[1..MaxNum] of pointer;
- initialRAM,
- currRAM : longint;
- i : integer;
- j, count : byte;
- ch : char;
-
-
- function initvideo : pointer;
- { initialize a video pointer, based on run-time determination of adapter type }
- const
- AdapterSeg = $0000;
- AdapterOff = $0449;
- Monochrome = 7;
- Mono = $b000;
- Color = $b800;
- var
- videoseg : word;
- begin
- if (Mem[AdapterSeg:AdapterOff] = Monochrome) then
- videoseg := Mono
- else
- videoseg := Color;
- initvideo := ptr(videoseg,0);
- end;
-
-
- procedure initmempointers;
- { by initializing all of your memory pointers, you can avoid the potential }
- { headaches of trying to free or reallocate a pointer which has not been }
- { allocated by DosAlloc(), and points to who knows where. the actual error }
- { monitoring occurs in the free(), realloc(), farfree(), and farrealloc() }
- { routines in ALLOC.PAS. }
- begin
- p := NIL ;
- for i := 1 to MaxNum do
- pbuffer[i] := NIL;
- end;
-
-
- procedure demoerrors;
- { an unexciting demo of memory error handling of pointers assigned to NIL }
- begin
- textcolor(lightred);
- p := realloc(p, 32768);
- if (p = NIL) then
- writeln('you cannot realloc() a pointer assigned to NIL')
- else
- writeln('memory reallocation was OK');
- free(p);
- if (AllocError <> 0) then
- writeln('you cannot free a pointer assigned to NIL')
- else
- writeln('memory was freed');
-
- p := malloc(1024);
- if (p = NIL) then
- writeln('you can alloc() a pointer assigned to NIL; but error occurred')
- else
- writeln('memory allocation was OK');
- free(p);
- if (AllocError <> 0) then
- writeln('you cannot free a pointer assigned to NIL')
- else
- writeln('memory was freed');
- free(p);
- if (AllocError <> 0) then
- writeln('you cannot free a pointer assigned to NIL')
- else
- writeln('memory was freed');
- writeln;
- writeln;
- textcolor(yellow);
- write('press any key to continue demo...');
- ch := readkey;
- textcolor(lightgray);
-
- { start from scratch again }
- clrscr;
- initmempointers;
- end;
-
-
- begin
- clrscr;
-
- { initial all pointers used for memory allocation }
- initmempointers;
-
-
- { un-comment this section to see how initializing to NIL is used to handle }
- { errors of incorrect attempts to use memory pointers which are improperly }
- { allocated. for example, if you try to reallocate memory, which DOS has }
- { not allocated through the use of malloc()/calloc(), unpredictable things }
- { could happen to you. by simply creating your own pointer initialization }
- { procedure, you should avoid any problems. }
-
- (* demoerrors; *)
-
-
- { show the initial memory status }
- textcolor(lightred);
- writeln('Initial memory conditions');
- textcolor(lightgray);
- writeln(coreleft,' bytes free in the near heap');
- initialRAM := farcoreleft;
- writeln(initialRAM,' bytes free in the far heap');
- writeln;
-
- { demo calloc(fp, size), note that fp can be any byte; 0 clears the RAM }
- textcolor(lightred);
- writeln('Now allocating memory with calloc');
- p := calloc(0, 32768); { get $8000 = 32k or 32768 }
- textcolor(lightgray);
- if (p = NIL) then
- writeln('calloc error = ',MemError[AllocError])
- else begin
- currRAM := farcoreleft;
- writeln(initialRAM-currRAM,' bytes allocated');
- writeln(currRAM,' bytes free');
- end;
-
- { demo free }
- textcolor(lightred);
- writeln('Now freeing reserved memory');
- free(p);
- textcolor(lightgray);
- if (AllocError <> 0) then
- writeln('free farmalloc error = ',MemError[AllocError])
- else
- writeln('previously allocated memory freed');
- writeln(farcoreleft,' bytes free');
- writeln;
-
- { demo farmalloc }
- textcolor(lightred);
- writeln('Now allocating memory with farmalloc');
- p := farmalloc($40000); { get $40000 = 256k or 262144 }
- textcolor(lightgray);
- if (p = NIL) then
- writeln('farmalloc error = ',MemError[AllocError])
- else begin
- currRAM := farcoreleft;
- writeln(initialRAM-currRAM,' bytes allocated');
- writeln(currRAM,' bytes free');
- end;
-
- { demo farrealloc }
- textcolor(lightred);
- writeln('Now reallocating memory with farrealloc');
- p := farrealloc(p,$20000); { get $20000 = 128k or 131072 }
- textcolor(lightgray);
- if (p = NIL) then
- writeln('farrealloc error = ',MemError[AllocError])
- else begin
- currRAM := farcoreleft;
- writeln('resized to ', initialRAM-currRAM,' bytes');
- writeln(currRAM,' bytes free');
- end;
- writeln;
-
- { demo realloc }
- textcolor(lightred);
- writeln('Now reallocating memory with realloc');
- p := realloc(p, 32768); { get $8000 = 32k or 32768 }
- textcolor(lightgray);
- if (p = NIL) then
- writeln('realloc error = ',MemError[AllocError])
- else begin
- currRAM := farcoreleft;
- writeln('resized to ', initialRAM-currRAM,' bytes');
- writeln(currRAM,' bytes free');
- end;
-
- { demo free again }
- textcolor(lightred);
- writeln('Now freeing reserved memory');
- free(p);
- textcolor(lightgray);
- if (AllocError <> 0) then
- writeln('free farmalloc error = ',MemError[AllocError])
- else
- writeln('previously allocated memory freed');
- writeln(farcoreleft,' bytes free');
- textcolor(yellow);
- write('press any key to continue...');
- ch := readkey;
- textcolor(lightgray);
-
-
- { now demo some actual use of allocated RAM: }
- { }
- { 1. Use calloc(fillpattern, size) to fill a newly allocated 1000 byte }
- { RAM buffer with a graphics char, and then write the individual }
- { char from memory using Mem[]. Note the use of Mem[], seg(), }
- { and the pointer pbuffer[1], along with 'i' used as the address }
- { of Mem[], to access the allocated memory. Since addresses are }
- { 0-based, 'i' ranges from 0 to 999 (n-1). The chr() function is }
- { then used to convert that location to a char for write(). }
- { }
- { 2. Fill some screens, save the results to RAM using malloc(), then }
- { swap them back to the screen using move(src,des,size). }
-
-
- { use calloc(), fill the RAM with char 178 (▓); you could use any ch 0-255 }
- pbuffer[1] := calloc(178,1000);
- if (pbuffer[1] = NIL) then begin
- writeLn('calloc error = ',MemError[AllocError]);
- halt(1);
- end;
- clrscr;
- textcolor(lightgreen);
-
- { now access the memory locations of the newly cleared allocation }
- for i := 0 to 999 do
- write(chr( Mem[ seg(pbuffer[1]^) : i] ));
-
- gotoxy(1,23);
- textcolor(lightcyan);
- writeln('calloc(',#178,',1000): requested a block of RAM and cleared it with char ',#178,'.');
- textcolor(lightgray);
- write('press any key to continue...');
- ch := readkey;
- { free up RAM }
- free(pbuffer[1]);
-
-
- { find the video adapter (mono or color) prior to using move() }
- videoptr := initvideo;
- count := 1;
-
- { seq. point to allocated memory with a pointer from an array of pointers }
- repeat
- gotoxy(1,1);
- pbuffer[count] := malloc(ScreenSize);
- if (pbuffer[count] = NIL) then begin
- writeLn('malloc error = ',MemError[AllocError]);
- halt(1);
- end;
-
- { now here's something original: fill the screen with numbers }
- textcolor((count+8) mod 15);
- for i := 1 to 80 do begin
- for j := 1 to 25 do begin
- write(count);
- end;
- end;
- textcolor(lightgray);
-
- { store the screen at the allocated position }
- move(videoptr^, pbuffer[count]^, ScreenSize);
- inc(count);
- until (count = MaxNum);
-
- { now restore screen from RAM to video memory, changing with readkey }
- textcolor(lightred);
- for count := 1 to MaxNum-1 do begin
- { wham! there's a new image }
- move(pbuffer[count]^, videoptr^, ScreenSize);
- gotoxy(1,25); clreol;
- write('Here is screen ',count,' again using move(). press any key to continue...');
- ch := readkey;
- end;
-
- { let's see pbuffer 1 again: wham! }
- move(pbuffer[1]^, videoptr^, ScreenSize);
- gotoxy(1,25); clreol;
- write('And the 1st screen one more time. press any key to continue...');
- ch := readkey;
-
- { and finally pbuffer MaxNum-1 again: wham! }
- move(pbuffer[MaxNum-1]^, videoptr^, ScreenSize);
- gotoxy(1,25); clreol;
- write('And finally, the last screen one more time. press any key to continue...');
- ch := readkey;
-
- { and before exiting, free-up RAM }
- clrscr;
- textcolor(lightred);
- writeln('Memory conditions before freeing RAM with video images');
- textcolor(lightgray);
- writeln(farcoreleft,' bytes free');
- writeln;
- for count := 1 to MaxNum-1 do
- { no error checking is done }
- free(pbuffer[count]);
-
- { verify all RAM was freed, comparing to starting RAM }
- textcolor(lightred);
- writeln('Memory conditions after freeing RAM with video images');
- textcolor(lightgray);
- currRAM := farcoreleft;
- writeln(initialRAM,' bytes free at the start of this program');
- writeln(currRAM,' bytes free after calling free(pbuffer[count])');
- writeln;
-
- { it if doesn't equal zero we're in trouble }
- writeln('difference between start and finishing RAM is: ',currRAM-initialRAM);
- writeln;
- writeln;
- textcolor(yellow);
- write('press any key to end demo...');
- ch := readkey;
- textcolor(lightgray);
- end.
-